#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<functional>

namespace lim
{

#include<iostream>
using namespace std;
#include<vector>

#include<functional>
        template <class T, class Container = vector<T>, class Compare = less<T> >

        class priority_queue

        {
        public:

            void swap(T& num1, T& num2)
            {
                T tmp = num1;
                num1 = num2;
                num2 = tmp;
                
            }
            priority_queue()
            {

            }
            template <class InputIterator>
            priority_queue(InputIterator first, InputIterator last)
            {
                while (first != last)
                {
                    c.push_back(*first);
                    ++first;
                }


                int parent = (c.size() - 2) / 2;
                while (parent >= 0)
                {


                    adjustdown(parent);
                    parent--;
                }
            }

            bool empty() const
            {
                return c.empty();
            }

            size_t size() const
            {
                return c.size();
            }
            const T& top() const
            {
                return c.front();
            }

            void push(const T& x)
            {
                c.push_back();
                adjustup(c.size()-1);
            }

            void pop()
            {
                swap(c[0], c[c.size() - 1]);
                c.pop_back();

                adjustdown(0);
            }

            void adjustdown(int root)
            {
                int parent = root;
                int child = root * 2 + 1;
                int size = c.size();
   
                while (child < size)
                {
                    if (child + 1 < size && comp(c[child], c[child + 1]))
                    {
                        child++;
                    }
                    if (comp(c[parent], c[child]))
                    {
                        swap(c[parent], c[child]);
                        parent = child;
                        child = child * 2 + 1;
                    }
                    else
                    {
                        return;
                    }
                }
            }

            void adjustup(int root)
            {
                int child = root;
                int parent = root / 2 - 1;
                while (child > 0)
                {
                    if (comp(c[parent], c[child]))
                    {
                        swap(c[parent], c[child]);
                        child = parent;
                        parent / 2 - 1;
                    }
                    else
                    {
                        return 0;
                    }
                }

            }

        private:

            Container c;

            Compare comp;

        };

 }







